<template>
  <div class="card smart-entry">
    <!-- max-width: ${showNodes ? '245px' : '0'}; -->
    <div class="left" :style="`min-width: ${showNodes ? '186px' : '0'}; border: ${showNodes ? '1px solid #ccc' : 'none'}`">
      <div class="tree" :style="`width: ${showNodes ? '100%' : '0%'}`">
        <!-- <el-tree ref="treeRef" :data="treeData" :props="defaultProps" node-key="name" highlight-current @node-click="selectNode">
          <template #default="{ data, node }">
            <div class="parent-node" :title="data.name">
              <img
                v-if="data.children && data.children.length"
                :src="node.expanded ? openedFolder : closedFolder"
                style="width: 16px; margin-right: 5px"
              />
              <img v-else src="@/assets/imgs/file.png" style="width: 16px; margin-right: 5px" />
              <span>{{ data.name }}</span>
            </div>
          </template>
        </el-tree> -->
        <el-tree
          ref="treeRef"
          :data="treeNodeList"
          :props="defaultProps"
          node-key="name"
          highlight-current
          @node-click="selectNode"
        >
          <template #default="{ data, node }">
            <div class="parent-node" :title="data.name">
              <img
                v-if="data.isDirectory"
                :src="node.expanded ? openedFolder : closedFolder"
                style="width: 16px; margin-right: 5px"
              />
              <img v-else src="@/assets/imgs/file.png" style="width: 16px; margin-right: 5px" />
              <div class="name-area">
                <span>{{ data.name }}</span>
                <el-icon title="编辑" @click.stop="editName(data)"><Edit /></el-icon>
                <el-icon title="删除" @click.stop="deleteNode(data)"><Delete /></el-icon>
              </div>
            </div>
          </template>
        </el-tree>
        <!-- <div v-if="showNodes && !treeData.length" class="no-data">
          <i class="iconfont icon-zanwushuju"></i>
          <span>暂无数据</span>
        </div> -->
        <div v-if="showNodes && !treeNodeList.length" class="no-data">
          <i class="iconfont icon-zanwushuju"></i>
          <span>暂无数据</span>
        </div>
        <div
          v-else
          :class="`handle ${showNodes ? '' : 'hideHandle'}`"
          @click="showNodes = !showNodes"
          :style="`transform: rotate(${showNodes ? '0deg' : '180deg'}); right: ${showNodes ? '0' : '-10px'}`"
          :title="showNodes ? '收起侧边栏' : '打开侧边栏'"
        >
          <i class="iconfont icon-dakaicebianlan"></i>
        </div>
      </div>
    </div>
    <div class="middle">
      <CustomCropper :curNodeImgUrl="curNodeImgUrl" @imgCroped="imgCroped" />
    </div>
    <div class="right">
      <div class="right-top">
        <el-divider>系统字段</el-divider>
        <div class="form-content">
          <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="auto" class="ruleForm">
            <div class="line">
              <el-form-item label="责任者：" prop="responsible">
                <el-input
                  v-model="ruleForm.responsible"
                  @focus="onInputFocus('responsible')"
                  @blur="onInputBlur('responsible')"
                  :ref="setInputRef('responsible')"
                />
              </el-form-item>
              <el-form-item label="序号：">
                <el-input
                  v-model="ruleForm.seriaNumber"
                  @focus="onInputFocus('seriaNumber')"
                  @blur="onInputBlur('seriaNumber')"
                  :ref="setInputRef('seriaNumber')"
                />
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="文号：">
                <el-input
                  v-model="ruleForm.docNumber"
                  @focus="onInputFocus('docNumber')"
                  @blur="onInputBlur('docNumber')"
                  :ref="setInputRef('docNumber')"
                />
              </el-form-item>
              <el-form-item label="扫描序号：">
                <el-input
                  v-model="ruleForm.scanNumber"
                  @focus="onInputFocus('scanNumber')"
                  @blur="onInputBlur('scanNumber')"
                  :ref="setInputRef('scanNumber')"
                />
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="题名：" prop="title">
                <el-input
                  v-model="ruleForm.title"
                  type="textarea"
                  :rows="2"
                  @focus="onInputFocus('title')"
                  @blur="onInputBlur('title')"
                  :ref="setInputRef('title')"
                />
              </el-form-item>
              <el-form-item label="备注：" prop="remark">
                <el-input
                  v-model="ruleForm.remark"
                  type="textarea"
                  :rows="2"
                  @focus="onInputFocus('remark')"
                  @blur="onInputBlur('remark')"
                  :ref="setInputRef('remark')"
                />
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="日期：" prop="date">
                <el-input
                  v-model="ruleForm.date"
                  @focus="onInputFocus('date')"
                  @blur="onInputBlur('date')"
                  :ref="setInputRef('date')"
                />
              </el-form-item>
              <el-form-item label="保管期限：">
                <el-select v-model="ruleForm.storagePeriod" placeholder="保管期限">
                  <el-option label="Zone one" value="shanghai" />
                  <el-option label="Zone two" value="beijing" />
                </el-select>
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="问题/机构：">
                <el-input
                  v-model="ruleForm.issue"
                  @focus="onInputFocus('issue')"
                  @blur="onInputBlur('issue')"
                  :ref="setInputRef('issue')"
                />
              </el-form-item>
              <el-form-item label="密级：">
                <el-select v-model="ruleForm.classification" placeholder="密级">
                  <el-option label="一级" value="shanghai" />
                  <el-option label="二级" value="beijing" />
                </el-select>
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="页数：" prop="pageNum">
                <el-input
                  v-model="ruleForm.pageNum"
                  @focus="onInputFocus('pageNum')"
                  @blur="onInputBlur('pageNum')"
                  :ref="setInputRef('pageNum')"
                />
              </el-form-item>
              <el-form-item label="年度：" prop="year">
                <el-input
                  v-model="ruleForm.year"
                  @focus="onInputFocus('year')"
                  @blur="onInputBlur('year')"
                  :ref="setInputRef('year')"
                />
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="标签：">
                <el-input
                  v-model="ruleForm.mark"
                  @focus="onInputFocus('mark')"
                  @blur="onInputBlur('mark')"
                  :ref="setInputRef('mark')"
                />
              </el-form-item>
              <el-form-item label="文种：">
                <el-select v-model="ruleForm.lang" placeholder="文种">
                  <el-option label="zh" value="shanghai" />
                  <el-option label="en" value="beijing" />
                </el-select>
              </el-form-item>
            </div>
            <div class="line">
              <el-form-item label="代字：">
                <el-input
                  v-model="ruleForm.code"
                  @focus="onInputFocus('code')"
                  @blur="onInputBlur('code')"
                  :ref="setInputRef('code')"
                />
              </el-form-item>
            </div>
          </el-form>
        </div>
      </div>
      <div class="btns">
        <div class="top">
          <el-button type="primary" :icon="ArrowLeftBold" @mousedown="allowBlur = true" @click="toFirst">首页</el-button>
          <el-button type="primary" :icon="ArrowRightBold" @mousedown="allowBlur = true" @click="toLast">末尾页</el-button>
          <div class="jump">
            <el-input
              v-model="numberInput"
              @mousedown="allowBlur = true"
              @blur="allowBlur = false"
              placeholder="跳转页码"
              @keyup.enter="jumpTo"
            >
              <template #suffix>
                <el-icon class="el-input__icon"><search /></el-icon>
              </template>
            </el-input>
          </div>
          <el-button type="primary" :icon="Aim" @click="toPrevParent">查看上一件</el-button>
        </div>
        <div class="btm">
          <el-button type="primary" @click="toNextParent">完成著录并自动跳到下一件</el-button>
        </div>
      </div>
    </div>
    <el-dialog v-model="editShow" title="编辑" width="400" custom-class="edit-dialog">
      <el-form>
        <el-form-item label="节点名称：">
          <el-input v-model="curEditNodePath" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="editShow = false">取消</el-button>
          <el-button type="primary" @click="confirm">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref, computed, nextTick, toRaw } from "vue";
import { ArrowLeftBold, ArrowRightBold, Aim } from "@element-plus/icons-vue";
import { ElTree, ElMessage } from "element-plus";
import axios from "axios";
import CustomCropper from "./CustomCropper.vue";
import { useDictionryStore } from "@/stores/modules/dictionary";
import useCurrentInstance from "@/utils/useCurrentInstance";
import openedFolder from "@/assets/imgs/opened_folder.png";
import closedFolder from "@/assets/imgs/folder.png";

const showNodes = ref(true); // 是否展示左侧文件树
const curNodeImgUrl = ref("");
const ruleFormRef = ref(); // 著录表单ref

const treeNodeList = ref<any[]>([]); // 用于保存文件树节点数据
const editShow = ref(false); // 编辑弹窗显示
const curEditNodePath = ref<any>(""); // 当前编辑节点路径
const oldEditNode = ref<any>({}); // 旧节点

const { proxy } = useCurrentInstance();

const { scanFileNodes } = useDictionryStore();
console.log("测试拿到树节点---", scanFileNodes);

const ruleForm = ref<any>({
  responsible: "",
  seriaNumber: "",
  docNumber: "",
  scanNumber: "",
  title: "",
  remark: "",
  date: "",
  storagePeriod: "",
  issue: "",
  classification: "",
  pageNum: 1,
  year: "2025",
  mark: "",
  lang: "",
  code: ""
});

const rules = reactive({
  responsible: [{ required: true, message: "请输入责任者", trigger: "blur" }],
  title: [{ required: true, message: "请输入题名", trigger: "change" }],
  pageNum: [{ required: true, message: "请输入页数", trigger: "blur" }],
  year: [{ required: true, message: "请输入年度", trigger: "blur" }]
});

const focusedKey = ref<string>("");
const inputRefs = new Map<string, HTMLInputElement>();
const allowBlur = ref(false); // 是否允许失焦
const pendingNextType = ref<string | null>(null);

// 节点导航 *** 开始
const treeRef = ref<any>();
const numberInput = ref<number>();
const currentNode = ref<any>(null);

const defaultProps = {
  children: "children",
  label: "name"
};

const treeData = Object.values(scanFileNodes).map(parent => {
  // 为每个父节点的子节点添加 _parent 属性
  const childrenWithParent = parent.children.map((child: any) => ({
    ...child,
    _parent: parent // 添加父节点引用
  }));
  return {
    ...parent,
    children: childrenWithParent
  };
});

const fileOrBlobToBase64 = (input: any): Promise<string> => {
  console.log("type:", Object.prototype.toString.call(input));
  return new Promise((resolve, reject) => {
    if (!(input instanceof Blob || input instanceof File)) {
      return reject(new TypeError("输入必须是 File 或 Blob"));
    }

    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(input);
  });
};

const bufferToBase64 = (buffer: ArrayBuffer): string => {
  return btoa(new Uint8Array(buffer).reduce((s, byte) => s + String.fromCharCode(byte), ""));
};

const selectNode = async (node: any) => {
  console.log("***** 当前选中节点 *****", node);
  currentNode.value = node;
  treeRef.value?.setCurrentKey(node.name);
  // curNodeImgUrl.value = "";
  // try {
  //   if (node.blob) {
  //     curNodeImgUrl.value = await fileOrBlobToBase64(node.blob);
  //   }
  // } catch (e) {
  //   ElMessage.error("文件预览失败");
  // }

  if (node.isDirectory) return;
  axios
    .get("api/api/MasterFile/file-stream", {
      responseType: "arraybuffer",
      params: {
        path: node.path
      }
    })
    .then(response => {
      const contentType = response.headers["content-type"] || "image/jpeg";
      const blob = new Blob([response.data], { type: contentType });
      const reader = new FileReader();
      reader.onloadend = () => {
        curNodeImgUrl.value = reader.result as string;
      };
      reader.readAsDataURL(blob);
    })
    .catch(error => {
      ElMessage.error("文件预览失败");
    });
};

const toFirst = () => {
  if (!currentNode.value?._parent) return;
  const first = currentNode.value._parent.children[0];
  selectNode({ ...first, _parent: currentNode.value._parent });
};

const toLast = () => {
  if (!currentNode.value?._parent) return;
  const last = currentNode.value._parent.children.at(-1);
  selectNode({ ...last, _parent: currentNode.value._parent });
};

const jumpTo = () => {
  // 自动跳转到下一个文件之前初始值要清除
  resetFormValue();
  ruleFormRef.value.resetFields(); // 重置表单
  const parent = currentNode.value._parent;
  const index = numberInput.value! - 1;
  if (!parent || index < 0 || index >= parent.children.length) {
    ElMessage.warning("索引超出范围");
    return;
  }
  selectNode({ ...parent.children[index], _parent: parent });
};

const toPrevParent = () => {
  // 自动跳转到上一件之前初始值要清除
  resetFormValue();
  ruleFormRef.value.resetFields(); // 重置表单
  const parentList = treeData;
  const currentParentIndex = parentList.findIndex(p => p.name === currentNode.value._parent.name);
  const targetIndex = currentParentIndex - 1 >= 0 ? currentParentIndex - 1 : parentList.length - 1;
  const targetParent = parentList[targetIndex];
  const first = targetParent.children[0];
  selectNode({ ...first, _parent: targetParent });
};

const toNextParent = () => {
  ruleFormRef.value.validate((valid: boolean) => {
    if (valid) {
      const parentList = treeData;
      const currentParentIndex = parentList.findIndex(p => p.name === currentNode.value._parent.name);
      const targetIndex = currentParentIndex + 1 < parentList.length ? currentParentIndex + 1 : 0;
      const targetParent = parentList[targetIndex];
      const first = targetParent.children[0];
      selectNode({ ...first, _parent: targetParent });

      // 自动跳转到下一件之后初始值要清除
      resetFormValue();
      ruleFormRef.value.resetFields(); // 重置表单
    }
  });
};

const resetFormValue = () => {
  ruleForm.value = {
    responsible: "",
    seriaNumber: "",
    docNumber: "",
    scanNumber: "",
    title: "",
    remark: "",
    date: "",
    storagePeriod: "",
    issue: "",
    classification: "",
    pageNum: 1,
    year: "2025",
    mark: "",
    lang: "",
    code: ""
  };
};

// 节点导航 *** 结束

// 输入框聚焦处理 *** 开始
const next = (type: string) => {
  if (!allowBlur.value) {
    pendingNextType.value = type;
    allowBlur.value = true;
    return;
  }

  console.log("真正执行 next", type);
  allowBlur.value = false;

  switch (type) {
    case "first":
      break;
    case "last":
      break;
    case "jump":
      break;
    case "pre":
      break;
    case "finish":
      break;
    default:
      break;
  }
};

const imgCroped = async () => {
  const res = await mockApi();
  proxy.$message.success("识别成功");
  ruleForm.value[focusedKey.value] = res;
};

const mockApi = () => {
  return new Promise((resolve, rejected) => {
    setTimeout(() => {
      resolve(`${focusedKey.value}--著录成功`);
    }, 500);
  });
};

const onInputFocus = (key: string) => {
  focusedKey.value = key;
};

const onInputBlur = (key: string) => {
  // 延迟判断是否真的切换到了别的 input
  if (!allowBlur.value) {
    setTimeout(() => {
      if (focusedKey.value === key) {
        // 没有换 input，强制 focus 回来
        inputRefs.get(key)?.focus();
      }
    }, 0);
    return;
  }
  // 真正 blur 后做跳转操作
  if (pendingNextType.value) {
    next(pendingNextType.value);
    pendingNextType.value = null;
  }
};

// 收集 input 的真实 DOM 引用
const setInputRef = (key: string) => (el: any) => {
  if (el?.$el?.querySelector) {
    const input = el.$el.querySelector("input");
    const textarea = el.$el.querySelector("textarea");
    if (input) inputRefs.set(key, input);
    if (textarea) inputRefs.set(key, textarea);
  }
};

// 输入框聚焦处理 *** 结束

// ******** 节点 ******* 开始
// 处理节点数据
const adaptTreeData = (apiData: any) => {
  return (apiData.Children || []).map((item: any) => ({
    label: item.Name,
    name: item.Name,
    path: item.Path,
    isDirectory: item.IsDirectory,
    size: item.Size,
    children: item.IsDirectory ? adaptTreeData(item) : null,
    rawData: item
  }));
};
// 请求节点数据
const getTreeNodeData = () => {
  proxy.$vueAxios
    .get("MasterFile/files", {
      path: "",
      recursive: true
    })
    .then((res: any) => {
      treeNodeList.value = adaptTreeData(res);
      console.log("treeData", treeNodeList.value);
      if (treeNodeList.value.length) {
        const firstParent = treeNodeList.value[0];
        const firstChild = firstParent.children[0];
        selectNode(firstChild); // 无需手动添加 _parent
      }
    });
};

const confirm = () => {
  console.log("confirm");
  proxy.$vueAxios
    .put("MasterFile/files", {
      oldPath: oldEditNode.value.path,
      newPath: curEditNodePath.value
    })
    .then((res: any) => {
      console.log("编辑res", res);
    });
};

// 编辑节点
const editName = (node: any) => {
  console.log("editNode", node);
  curEditNodePath.value = node.path;
  oldEditNode.value = node;
  editShow.value = true;
};

// 删除节点
const deleteNode = (node: any) => {
  if (node.isDirectory) {
    proxy.$vueAxios.delete2(`MasterFile/folders?path=${encodeURIComponent(node.path)}`).then((res: any) => {
      proxy.$message.success("删除成功");
      getTreeNodeData();
    });
    return;
  }
  proxy.$vueAxios.delete2(`MasterFile/files?path=${encodeURIComponent(node.path)}`).then((res: any) => {
    proxy.$message.success("删除成功");
    getTreeNodeData();
  });
};

onMounted(() => {
  // if (treeData.length) {
  //   const firstParent = treeData[0];
  //   const firstChild = firstParent.children[0];
  //   selectNode(firstChild); // 无需手动添加 _parent
  // }

  // 测试新节点
  getTreeNodeData();
});
</script>
<style scoped>
::v-deep(.el-tree-node.is-current > .el-tree-node__content > .parent-node) {
  color: #ffffff;
  background-color: var(--el-color-primary) !important;
}
::v-deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
  background-color: unset;
}
::v-deep(.el-tree__empty-block) {
  display: none;
}
</style>
<style lang="scss" scoped>
.smart-entry {
  display: flex;
  height: 100%;
  .left {
    position: relative;
    // width: 230px;
    min-width: 186px;
    height: 100%;

    // max-width: 230px;
    padding-right: 6px;
    border: 1px solid #cccccc;
    border-right: 4px solid #f5f5f5;
    border-radius: 4px;
    transition: all 0.3s;
    .tree {
      width: 100%;
      height: 100%;
      padding-bottom: 6px;
      transition: all 0.3s;
      .parent-node {
        display: flex;
        align-items: center;
        width: 88%;
        padding: 4px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        .name-area {
          display: flex;
          align-items: center;
          .el-icon {
            margin: 3px 0 0 8px;
          }
        }
      }
      .no-data {
        position: absolute;
        top: 50%;
        left: 50%;
        display: flex;
        flex-direction: column;
        align-items: center;
        font-size: 13px;
        transform: translate(-50%, -50%);
        .icon-zanwushuju {
          font-size: 58px;
          color: var(--el-color-primary);
        }
        span {
          margin-top: 10px;
          color: var(--el-text-color-regular);
        }
      }
    }
    .handle {
      position: absolute;
      top: 1px;

      //   transform: translateY(-50%);
      right: 0;
      padding: 0 4px;
      cursor: pointer;
      background-color: var(--el-bg-color);
      transition: all 0.3s;
      .icon-dakaicebianlan {
        font-size: 20px;
      }
    }
    .hideHandle {
      top: 50%;
      transform: translateY(-50%);
    }
  }
  .middle {
    flex: 1;
    height: 100%;
    padding: 0 6px;
    .container {
      border: 1px solid #cccccc;
      border-radius: 4px;
    }
  }
  .right {
    display: flex;
    flex: 1;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
    padding-bottom: 6px;
    padding-left: 6px;
    overflow-y: scroll;
    border: 1px solid #cccccc;
    border-left: 4px solid #f5f5f5;
    border-radius: 4px;
    .el-divider--horizontal {
      width: 86%;
      margin: 24px auto;
      :deep(.el-divider__text) {
        font-size: 16px;
      }
    }
    .form-content {
      margin-top: 30px;
      .line {
        display: flex;
        justify-content: space-between;
        .el-form-item {
          width: 49%;
          :deep(.el-form-item__label) {
            font-size: 13px;
          }
          .el-input,
          .el-textarea {
            font-size: 13px;
          }
        }
      }
    }
    .btns {
      .el-button {
        font-size: 13px;
      }
      .top {
        display: flex;
        align-items: center;
        justify-content: space-around;
        .el-button,
        .jump {
          width: 23%;
          margin-left: 0;
        }
      }
      .btm {
        margin-top: 20px;
        text-align: center;
        .el-button {
          width: 98%;
        }
      }
    }
  }
}
.edit-dialog {
  .el-form-item {
    margin-bottom: 0;
  }
}
:deep(.el-dialog__body) {
  padding: 20px;
}
</style>
